import config from '../config'

const rawHeaderLen = 16
const packetOffset = 0
const headerOffset = 4
const verOffset = 6
const opOffset = 8
const seqOffset = 12
const fixSubSeq = 1566555576000

let ws = null
var DELAY = 15000
let textDecoder = new TextDecoder()
let textEncoder = new TextEncoder()
let heartbeatInterval = null

function mergeArrayBuffer(ab1, ab2) {
    let u81 = new Uint8Array(ab1),
        u82 = new Uint8Array(ab2),
        res = new Uint8Array(ab1.byteLength + ab2.byteLength)
    res.set(u81, 0)
    res.set(u82, ab1.byteLength)
    return res.buffer
}

export default {
    init(onMessage, onError) {
        if (!ws) {
            // 实例化socket对象
            ws = new WebSocket(config.socketUrl)
        }

        // 显示指定类型的数据
        ws.binaryType = 'arraybuffer'

        ws.onopen = () => {
            // console.log('打开连接')
            this.auth()
        }

        // 客户端接收消息
        ws.onmessage = event => {
            console.info('onmessge trigger')
            let data = event.data
            let dataView = new DataView(data, 0)
            let packetLen = dataView.getInt32(packetOffset)
            let headerLen = dataView.getInt16(headerOffset)
            let ver = dataView.getInt16(verOffset)
            let op = dataView.getInt32(opOffset)
            let seq = dataView.getInt32(seqOffset)
            // console.log('receiveHeader: packetLen=' + packetLen, 'headerLen=' + headerLen, 'ver=' + ver, 'op=' + op, 'seq=' + seq)

            switch (op) {
                case 8: // 认证成功返回
                    // 开始发送心跳
                    onMessage && onMessage(JSON.stringify({
                        open: true
                    }))
                    this.heartbeat()
                    let _this = this
                    heartbeatInterval = setInterval(_this.heartbeat, 30 * 1000) // 2分钟发一次心跳
                    // 解包
                    for (let offset = 0; offset < data.byteLength; offset += packetLen) {
                        let packetLen = dataView.getInt32(offset)
                        let headerLen = dataView.getInt16(offset + headerOffset)
                        let ver = dataView.getInt16(verOffset)
                        let msgBody = textDecoder.decode(data.slice(offset + headerLen, offset + packetLen))
                        // 回调
                        // onMessage && onMessage(msgBody)
                    }
                    break
                case 5:
                    // 解包
                    for (let offset = 0; offset < data.byteLength; offset += packetLen) {
                        let packetLen = dataView.getInt32(offset)
                        let headerLen = dataView.getInt16(offset + headerOffset)
                        let ver = dataView.getInt16(verOffset)
                        let msgBody = textDecoder.decode(data.slice(offset + headerLen, offset + packetLen))
                        // console.error('msgBody' + msgBody)
                        // 回调
                        onMessage && onMessage(msgBody)
                    }
                    break
                case 21:
                    // 解包
                    for (let offset = 0; offset < data.byteLength; offset += packetLen) {
                        let packetLen = dataView.getInt32(offset)
                        let headerLen = dataView.getInt16(offset + headerOffset)
                        let ver = dataView.getInt16(verOffset)
                        let msgBody = textDecoder.decode(data.slice(offset + headerLen, offset + packetLen))
                        // console.error('msgBody' + msgBody)
                        let obj = JSON.parse(msgBody)
                        if (obj.code == 313) {
                            obj.data.msgId = seq + fixSubSeq
                            obj.data.stage = -3
                            obj.data.tipsMsg = obj.msg
                            onMessage && onMessage(JSON.stringify(obj))
                        }
                        // 回调
                        // onMessage && onMessage(msgBody)
                    }
                    break
                case 23:
                    onError && onError({
                        code: 423,
                        msg: '此账号已在别的浏览器登录'
                    })
                    break
                case 24:
                    onError && onError({
                        code: 424,
                        msg: 'APP端已退出WEB登录'
                    })
                    break
                case 28:
                    onError && onError({
                        code: 428,
                        msg: 'APP退出登录'
                    })
                    break
            }
        }

        // ERROR
        ws.onerror = error => {
            console.log('error:' + error)
            onError && onError(error)
        }

        ws.onclose = () => {
            // console.log('连接关闭')
            if (heartbeatInterval) clearInterval(heartbeatInterval)
            ws = null
            onError && onError({
                code: 480,
                msg: '无网络，请重新连接'
            })
        }
    },
    // 发送消息的时候触发
    send(msgObj) {
        var headerBuf = new ArrayBuffer(rawHeaderLen)
        var headerView = new DataView(headerBuf, 0)
        var bodyBuf = textEncoder.encode(JSON.stringify(msgObj))

        headerView.setInt32(packetOffset, rawHeaderLen + bodyBuf.byteLength)
        headerView.setInt16(headerOffset, rawHeaderLen)
        headerView.setInt16(verOffset, 3001) // 3000 - 4000 为web版
        headerView.setInt32(opOffset, 4) // 发送消息
        if (msgObj.data && msgObj.data.msgId) {
            headerView.setInt32(seqOffset, msgObj.data.msgId - fixSubSeq)
        } else {
            headerView.setInt32(seqOffset, 1)
        }
        ws.send(mergeArrayBuffer(headerBuf, bodyBuf))
    },
    close() {
        // console.log('执行了关闭的方法')
        var headerBuf = new ArrayBuffer(rawHeaderLen)
        var headerView = new DataView(headerBuf, 0)
        headerView.setInt32(packetOffset, rawHeaderLen)
        headerView.setInt16(headerOffset, rawHeaderLen)
        headerView.setInt16(verOffset, 3001) // 3000 - 4000 为web版
        headerView.setInt32(opOffset, 29) // 2:发送心跳  3:服务端心跳和回执
        headerView.setInt32(seqOffset, 1)
        ws.send(headerBuf)
        ws.onclose()
    },
    // 授权
    auth() {
        let token = sessionStorage.getItem('key')
        let headerBuf = new ArrayBuffer(rawHeaderLen)
        let headerView = new DataView(headerBuf, 0)
        let bodyBuf = textEncoder.encode(token)

        headerView.setInt32(packetOffset, rawHeaderLen + bodyBuf.byteLength)
        headerView.setInt16(headerOffset, rawHeaderLen)
        headerView.setInt16(verOffset, 3001) // 3000 - 4000 为web版
        headerView.setInt32(opOffset, 7) // 发送消息
        headerView.setInt32(seqOffset, 1)

        ws.send(mergeArrayBuffer(headerBuf, bodyBuf))
    },
    heartbeat() {
        var headerBuf = new ArrayBuffer(rawHeaderLen)
        var headerView = new DataView(headerBuf, 0)
        headerView.setInt32(packetOffset, rawHeaderLen)
        headerView.setInt16(headerOffset, rawHeaderLen)
        headerView.setInt16(verOffset, 3001) // 3000 - 4000 为web版
        headerView.setInt32(opOffset, 2) // 2:发送心跳  3:服务端心跳和回执
        headerView.setInt32(seqOffset, 1)

        ws.send(headerBuf)
        // console.log('send: heartbeat')
    }
}
